package com.czkt.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.czkt.config.CustomRealm;
import com.czkt.pojo.SysRight;
import com.czkt.pojo.SysRole;
import com.czkt.pojo.SysRoleRight;
import com.czkt.service.ISysRightService;
import com.czkt.service.ISysRoleRightService;
import com.czkt.service.ISysRoleService;
import com.czkt.service.SysUserService;
import com.czkt.utils.PageUtile;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.mgt.RealmSecurityManager;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.web.filter.mgt.DefaultFilterChainManager;
import org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.AbstractShiroFilter;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.context.support.WebApplicationContextUtils;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author liu
 * @since 2024-06-21
 */
@Controller
@RequestMapping("/role")
public class SysRoleController {

    @Autowired
    ISysRoleService sysRoleService;


    @Autowired
    ISysRightService sysRightService;


    @Autowired
    ISysRoleRightService sysRoleRightService;

    @Autowired
    SysUserService sysUserService;

    @RequestMapping("/list")
    public Object getRoleList(SysRole sysRole, @RequestParam(defaultValue = "1") Integer pageIndex, @RequestParam(defaultValue = "2") Integer pageSize, Model model) {

        IPage<SysRole> page = new Page<SysRole>(pageIndex, pageSize);

        QueryWrapper<SysRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .like(StringUtils.hasText(sysRole.getRoleName())
                        , SysRole::getRoleName, sysRole.getRoleName());

        Page<SysRole> page1 = (Page<SysRole>) sysRoleService.page(page, queryWrapper);

        PageUtile<SysRole> pageUtile = new PageUtile<SysRole>();
        //复制对象的值
        BeanUtils.copyProperties(page1, pageUtile);

        model.addAttribute("rolePage", pageUtile);
        model.addAttribute("roleName", sysRole.getRoleName());

        return "role/list";
    }


    /**
     * 定义跳转到新增页的方法
     */
    @RequestMapping("/add")
    public Object toAdd(Model model) {


        model.addAttribute("rights", sysRightService.list());

        return "role/add";
    }

    /**
     * 定义跳转到新增页的方法
     */
    @RequestMapping("/save")
    @Transactional
    public Object saveOrUpdate(SysRole sysRole, String[] rightCodes, Model model) {

        boolean result = sysRoleService.saveOrUpdate(sysRole);
        if (result) {

            //先删除原有的权限  再添加新的权限
            QueryWrapper<SysRoleRight> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(SysRoleRight::getRfRoleId, sysRole.getRoleId());
            sysRoleRightService.remove(queryWrapper);

            //新增角色成功则将角色权限添加
            List<SysRoleRight> list = new ArrayList<>();
            for (String rightCode : rightCodes) {
                SysRoleRight sysRoleRight = new SysRoleRight();
                sysRoleRight.setRfRightCode(rightCode);
                sysRoleRight.setRfRoleId(sysRole.getRoleId());
                list.add(sysRoleRight);
            }
            sysRoleRightService.saveBatch(list);

            //刷新缓存中shiro的数据
            //shiro只提供了清除缓存的功能
//            CustomRealm realm=new CustomRealm();
//            realm.clearAllCachedAuthorizationInfo();
            DefaultWebSecurityManager securityManager= (DefaultWebSecurityManager) SecurityUtils.getSecurityManager();
            CustomRealm realm= (CustomRealm) securityManager.getRealms().iterator().next();
            realm.clearAllCachedAuthorizationInfo();

//            //刷新shiro过滤器中的权限
//            reloadFilterChainDefinitions();
//            //清除所有缓存
//            reloadCacheAuthori();




            return "redirect:/role/list";
        } else if (sysRole.getRoleId() == 0) {
            return "redirect:/role/add";
        } else {
            return "redirect:/role/edit?usrId=" + sysRole.getRoleId();
        }

    }


//    private void reloadCacheAuthori(){
//        //清除当前登录用户的权限缓存
//        DefaultWebSecurityManager defaultWebSecurityManager = (DefaultWebSecurityManager) SecurityUtils.getSecurityManager();
//        Collection<Realm> realms= defaultWebSecurityManager.getRealms();
//        if ( realms != null && !realms.isEmpty()) {
//            Iterator var3 = realms.iterator();
//            while(var3.hasNext()) {
//                Realm realm = (Realm)var3.next();
//                if (realm instanceof CustomRealm) {
//                    CustomRealm tempReaml= (CustomRealm) realm;
//                    tempReaml.clearAllCachedAuthorizationInfo();
//                }
//            }
//        }
//    }



    private   Map<String, String> loadFilterChainDefinitions(){
        //配置资源认证规则
        Map<String, String> urlMap = new LinkedHashMap<>();
        urlMap.put("/css/*", "anon");
        urlMap.put("/js/*", "anon");
        urlMap.put("/fonts/*", "anon");
        urlMap.put("/images/*", "anon");
        urlMap.put("/localcss/*", "anon");
        urlMap.put("/localjs/*", "anon");

        urlMap.put("/doLogin", "anon");

        urlMap.put("/logout", "anon");

//        登录页面
        urlMap.put("/", "anon");

        List<SysRight> rightList = sysRightService.list();
        for (SysRight sysRight : rightList) {
            if (StringUtils.hasText(sysRight.getRightUrl())) {
                urlMap.put(sysRight.getRightUrl(), "perms[" + sysRight.getRightCode() + "]");
            }
        }
        urlMap.put("/**", "authc");
        return urlMap;
    }

    /**
     * 重新配置权限规则
     */
    private void reloadFilterChainDefinitions() {
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            ServletContext servletContext = request.getSession().getServletContext();
            AbstractShiroFilter shiroFilter = (AbstractShiroFilter) WebApplicationContextUtils
                    .getRequiredWebApplicationContext(servletContext).getBean("shiroFilterFactoryBean");
            synchronized (shiroFilter) {
                // 获取过滤管理器
                PathMatchingFilterChainResolver filterChainResolver = (PathMatchingFilterChainResolver) shiroFilter.getFilterChainResolver();
                DefaultFilterChainManager manager = (DefaultFilterChainManager) filterChainResolver.getFilterChainManager();
                // 清空初始权限配置
                manager.getFilterChains().clear();
                // 重新加载动态权限，配置权限验证规则
                Map<String, String> chains = loadFilterChainDefinitions();
                // System.out.println("chains-------"+chains);
                for (Map.Entry<String, String> entry : chains.entrySet()) {
                    String url = entry.getKey();
                    String chainDefinition = entry.getValue().trim().replace(" ", "");
                    manager.createChain(url, chainDefinition);
                }
                System.out.println("更新权限成功！！");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 定义跳转到新增页的方法
     */
    @RequestMapping("/edit")
    public Object toEdit(long roleId, Model model) {
        model.addAttribute("role", sysRoleService.getById(roleId));
        model.addAttribute("rights", sysRightService.list());
        //获取用户拥有的权限
        List<SysRoleRight> roleRightList = sysUserService.getRightListByRoleId(roleId);

        Set<String> roleRights = roleRightList.stream()
                .map(roleRight -> roleRight.getRfRightCode())
                .collect(Collectors.toSet());

        model.addAttribute("roleRights", roleRights);
        return "role/edit";
    }


}
